home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / oleo-1_4.lha / oleo-1.4 / sylk.c < prev    next >
C/C++ Source or Header  |  1993-03-30  |  16KB  |  817 lines

  1. /*    Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "funcdef.h"
  20. #include <stdio.h>
  21. #include "sysdef.h"
  22. #include "io-generic.h"
  23. #include "io-abstract.h"
  24. #include "global.h"
  25. #include "cell.h"
  26. #include "line.h"
  27. #include "io-term.h"
  28. #include "lists.h"
  29. #include "io-utils.h"
  30. #include "ref.h"
  31. #include "regions.h"
  32. #include "window.h"
  33. #include "info.h"
  34. #include "cmd.h"
  35.  
  36.  
  37. /* These functions read and write Microsoft Multiplan SYLK style files
  38.  * as well as SYLK-NOA0 files.  SYLK-NOA0 is the same as SYLK except that
  39.  * cell references are in rc format instead of a0 format.
  40.  */
  41.  
  42. int sylk_a0 = 1;        /* Determines sylk vs. sylk_noa0 format. */
  43.  
  44. void
  45. sylk_read_file (fp, ismerge)
  46.      FILE *fp;
  47.      int ismerge;
  48. {
  49.   char *ptr;
  50.   CELLREF crow = 0, ccol = 0, czrow = 0, czcol = 0;
  51.   int lineno;
  52.   char cbuf[1024];
  53.   char expbuf[1024];
  54.   char *vname, *vval;
  55.   int vlen = 0;
  56.   int cprot;
  57.   char *cexp, *cval;
  58.   CELL *cp;
  59.   struct rng rng;
  60.   int fmt = 0;
  61.   int jst = 0;
  62.   long mx_row = MAX_ROW, mx_col = MAX_COL;
  63.   int next_a0;
  64.   int old_a0;
  65.  
  66.   old_a0 = a0;
  67.   next_a0 = old_a0;
  68.   a0 = sylk_a0;
  69.  
  70.   lineno = 0;
  71.   if (!ismerge)
  72.     clear_spreadsheet ();
  73.   while (fgets (cbuf, sizeof (cbuf), fp))
  74.     {
  75.       lineno++;
  76.       if (lineno % 50 == 0)
  77.     io_info_msg ("Line %d", lineno);
  78.       if (ptr = (char *)index (cbuf, '\n'))
  79.     *ptr = '\0';
  80.       ptr = cbuf;
  81.       switch (*ptr)
  82.     {
  83.     case 'I':        /* ID field, ignored */
  84.       if (ptr[1] != 'D' || ptr[2] != ';')
  85.         goto bad_field;
  86.       break;
  87.     case 'F':        /* Format field */
  88.       vlen = 0;
  89.       ptr++;
  90.       while (*ptr)
  91.         {
  92.           if (*ptr != ';')
  93.         goto bad_field;
  94.           ptr++;
  95.           switch (*ptr++)
  96.         {
  97.           int clo, chi, cwid;
  98.         case 'C':    /* Column from rows 1 to 255 */
  99.           czcol = astol (&ptr);
  100.           vlen = 2;
  101.           break;
  102.  
  103.         case 'D':    /* Default format */
  104.           switch (*ptr++)
  105.             {
  106.             case 'G':
  107.               default_fmt = FMT_GEN - PRC_FLT;
  108.               break;
  109.             case 'E':
  110.               default_fmt = FMT_EXP - PRC_FLT;
  111.               break;
  112.             case 'F':
  113.               default_fmt = FMT_FXT - PRC_FLT;
  114.               break;
  115.             case '$':
  116.               default_fmt = FMT_DOL - PRC_FLT;
  117.               break;
  118.             case '*':    /* * format implemented as +- format */
  119.               default_fmt = FMT_GPH;
  120.               break;
  121.             case ',':    /* JF */
  122.               default_fmt = FMT_CMA - PRC_FLT;
  123.               break;
  124.             case 'U':
  125.               default_fmt = FMT_USR - PRC_FLT;
  126.               break;
  127.             case '%':
  128.               default_fmt = FMT_PCT - PRC_FLT;
  129.               break;
  130.             case 'H':
  131.               default_fmt = FMT_HID;
  132.               break;
  133.               /* End of JF */
  134.             case 'C':    /* Continuous not supported */
  135.             default:
  136.               io_error_msg ("Line %d: format %c not supported", lineno, ptr[-1]);
  137.               break;
  138.             }
  139.           if (*ptr == 'F')
  140.             {
  141.               default_fmt += PRC_FLT;
  142.               ptr++;
  143.             }
  144.           else
  145.             default_fmt += astol (&ptr);
  146.           switch (*ptr++)
  147.             {
  148.             case 'C':
  149.               default_jst = JST_CNT;
  150.               break;
  151.             case 'L':
  152.               default_jst = JST_LFT;
  153.               break;
  154.             case 'R':
  155.               default_jst = JST_RGT;
  156.               break;
  157.             case 'G':    /* General format not supported */
  158.             default:
  159.               io_error_msg ("Line %d: Alignment %c not supported", lineno, ptr[-1]);
  160.               break;
  161.             }
  162.           default_width = astol (&ptr);
  163.           break;
  164.  
  165.         case 'F':
  166.           switch (*ptr++)
  167.             {
  168.             case 'D':
  169.               fmt = FMT_DEF;
  170.               break;
  171.             case 'G':
  172.               fmt = FMT_GEN - PRC_FLT;
  173.               break;
  174.             case 'E':
  175.               fmt = FMT_EXP - PRC_FLT;
  176.               break;
  177.             case 'F':
  178.               fmt = FMT_FXT - PRC_FLT;
  179.               break;
  180.             case '$':
  181.               fmt = FMT_DOL - PRC_FLT;
  182.               break;
  183.             case '*':    /* JF implemented as +- format */
  184.               fmt = FMT_GPH;
  185.               break;
  186.             case ',':    /* JF */
  187.               fmt = FMT_CMA - PRC_FLT;
  188.               break;
  189.             case 'U':
  190.               fmt = FMT_USR - PRC_FLT;
  191.               break;
  192.             case '%':
  193.               fmt = FMT_PCT - PRC_FLT;
  194.               break;
  195.             case 'H':
  196.               fmt = FMT_HID;
  197.               break;    /* END of JF */
  198.             case 'C':
  199.             default:
  200.               io_error_msg ("Line %d: format %c not supported", lineno, ptr[-1]);
  201.               fmt = FMT_DEF;
  202.               break;
  203.             }
  204.           if (*ptr == 'F')
  205.             {
  206.               fmt += PRC_FLT;
  207.               ptr++;
  208.             }
  209.           else
  210.             fmt += astol (&ptr);
  211.           switch (*ptr++)
  212.             {
  213.             case 'C':
  214.               jst = JST_CNT;
  215.               break;
  216.             case 'L':
  217.               jst = JST_LFT;
  218.               break;
  219.             case 'R':
  220.               jst = JST_RGT;
  221.               break;
  222.             case 'D':
  223.               jst = JST_DEF;
  224.               break;
  225.             default:
  226.               io_error_msg ("Line %d: Alignment %c not supported", lineno, ptr[-1]);
  227.               jst = JST_DEF;
  228.               break;
  229.             }
  230.           vlen = 1;
  231.           break;
  232.         case 'R':    /* Row from cols 1 to 63 */
  233.           czrow = astol (&ptr);
  234.           vlen = 4;
  235.           break;
  236.  
  237.         case 'W':    /* Width of clo to chi is cwid */
  238.           clo = astol (&ptr);
  239.           chi = astol (&ptr);
  240.           cwid = astol (&ptr) + 1;
  241.           for (; clo <= chi; clo++)
  242.             set_width (clo, cwid);
  243.           break;
  244.  
  245.         case 'H':    /* JF: extension */
  246.           clo = astol (&ptr);
  247.           chi = astol (&ptr);
  248.           cwid = astol (&ptr) + 1;
  249.           for (; clo <= chi; clo++)
  250.             set_height (clo, cwid);
  251.           break;
  252.         case 'X':
  253.           ccol = astol (&ptr);
  254.           break;
  255.         case 'Y':
  256.           crow = astol (&ptr);
  257.           break;
  258.  
  259.         default:
  260.           goto bad_field;
  261.         }
  262.         }
  263.       switch (vlen)
  264.         {
  265.         case 1:
  266.           cp = find_or_make_cell (crow, ccol);
  267.           SET_FMT (cp, fmt);
  268.           SET_JST (cp, jst);
  269.           break;
  270.         case 2:
  271.           rng.lr = MIN_ROW;
  272.           rng.lc = czcol;
  273.           rng.hr = mx_row;
  274.           rng.hc = czcol;
  275.           make_cells_in_range (&rng);
  276.           while (cp = next_cell_in_range ())
  277.         {
  278.           SET_FMT (cp, fmt);
  279.           SET_JST (cp, jst);
  280.         }
  281.           break;
  282.         case 4:
  283.           rng.lr = czrow;
  284.           rng.lc = MIN_COL;
  285.           rng.hr = czrow;
  286.           rng.hc = mx_col;
  287.           make_cells_in_range (&rng);
  288.           while (cp = next_cell_in_range ())
  289.         {
  290.           SET_FMT (cp, fmt);
  291.           SET_JST (cp, jst);
  292.         }
  293.           break;
  294.         default:
  295.           break;
  296.         }
  297.       break;
  298.  
  299.     case 'B':        /* Boundry field, ignored */
  300.       ptr++;
  301.       while (*ptr)
  302.         {
  303.           if (*ptr != ';')
  304.         goto bad_field;
  305.           ptr++;
  306.           switch (*ptr++)
  307.         {
  308.         case 'X':
  309.           mx_col = astol (&ptr);
  310.           if (mx_col > MAX_COL)
  311.             {
  312.               io_error_msg ("Boundry column %lu too large!", mx_col);
  313.               mx_col = MAX_COL;
  314.             }
  315.           break;
  316.         case 'Y':
  317.           mx_row = astol (&ptr);
  318.           if (mx_row > MAX_ROW)
  319.             {
  320.               io_error_msg ("Boundry row %lu too large!", mx_row);
  321.               mx_row = MAX_ROW;
  322.             }
  323.           break;
  324.         default:
  325.           goto bad_field;
  326.         }
  327.         }
  328.       break;
  329.  
  330.     case 'N':        /* A Name field */
  331.       if (ptr[1] != 'N')
  332.         goto bad_field;
  333.       ptr += 2;
  334.       vname = 0;
  335.       vval = 0;
  336.       while (*ptr)
  337.         {
  338.           if (*ptr != ';')
  339.         goto bad_field;
  340.           *ptr++ = '\0';
  341.           switch (*ptr++)
  342.         {
  343.         case 'N':    /* Name is */
  344.           vname = ptr;
  345.           while (*ptr && *ptr != ';')
  346.             ptr++;
  347.           vlen = ptr - vname;
  348.           break;
  349.         case 'E':    /* Expression is */
  350.           vval = ptr;
  351.           while (*ptr && *ptr != ';')
  352.             ptr++;
  353.           break;
  354.         default:
  355.           --ptr;
  356.           goto bad_field;
  357.         }
  358.         }
  359.       if (!vname || !vval)
  360.         goto bad_field;
  361.       *ptr = '\0';
  362.       ptr = new_var_value (vname, vlen, vval);
  363.       if (ptr)
  364.         io_error_msg ("Line %d: Couldn't set %.*s to %s: %s", lineno, vlen, vname, vval, ptr);
  365.       break;
  366.  
  367.     case 'C':        /* A Cell entry */
  368.       cprot = 0;
  369.       cval = 0;
  370.       cexp = 0;
  371.       cval = 0;
  372.       ptr++;
  373.       while (*ptr)
  374.         {
  375.           int quotes;
  376.  
  377.           if (*ptr != ';')
  378.         goto bad_field;
  379.           *ptr++ = '\0';
  380.           switch (*ptr++)
  381.         {
  382.         case 'X':
  383.           ccol = astol (&ptr);
  384.           break;
  385.         case 'Y':
  386.           crow = astol (&ptr);
  387.           break;
  388.         case 'R':
  389.           czrow = astol (&ptr);
  390.           break;
  391.         case 'C':
  392.           czcol = astol (&ptr);
  393.           break;
  394.         case 'P':    /* This cell is Protected */
  395.           cprot++;
  396.           break;
  397.         case 'K':    /* This cell's Konstant value */
  398.           cval = ptr;
  399.           quotes = 0;
  400.           while (*ptr && (*ptr != ';' || quotes > 0))
  401.             if (*ptr++ == '"')
  402.               quotes = !quotes;
  403.           break;
  404.         case 'E':    /* This cell's Expression */
  405.           cexp = ptr;
  406.           quotes = 0;
  407.           while (*ptr && (*ptr != ';' || quotes > 0))
  408.             if (*ptr++ == '"')
  409.               quotes = !quotes;
  410.  
  411.           break;
  412.         case 'G':
  413.           strcpy (expbuf, cval);
  414.           break;
  415.         case 'D':
  416.           strcpy (expbuf, cexp);
  417.           break;
  418.         case 'S':
  419.           cexp = expbuf;
  420.           break;
  421.         default:
  422.           --ptr;
  423.           goto bad_field;
  424.         }
  425.         }
  426.       *ptr = '\0';
  427.       if (cexp && cval && strcmp (cexp, cval))
  428.         {
  429.           ptr = read_new_value (crow, ccol, cexp, cval);
  430.           if (ptr)
  431.         {
  432.           io_error_msg ("Line %d: %d,%d: Read '%s' %s", lineno, crow, ccol, cexp, ptr);
  433.           break;
  434.         }
  435.         }
  436.       else if (cval)
  437.         {
  438.           ptr = read_new_value (crow, ccol, 0, cval);
  439.           if (ptr)
  440.         {
  441.           io_error_msg ("Line %d: %d,%d: Val '%s' %s", lineno, crow, ccol, cexp, ptr);
  442.           break;
  443.         }
  444.         }
  445.       else if (cexp)
  446.         {
  447.           ptr = read_new_value (crow, ccol, cexp, 0);
  448.           if (ptr)
  449.         {
  450.           io_error_msg ("Line %d: %d,%d: Exp '%s' %s", lineno, crow, ccol, cexp, ptr);
  451.           break;
  452.         }
  453.         }
  454.       if (cprot)
  455.         SET_LCK (find_or_make_cell (crow, ccol), LCK_LCK);
  456.       if (ismerge)
  457.         push_cell (crow, ccol);
  458.       /* ... */
  459.       break;
  460.     case 'E':
  461.       break;
  462.     case 'W':
  463.       io_read_window_config (ptr + 2);
  464.       break;
  465.     case 'U':
  466.       /* JF extension:  read user-defined formats */
  467.       read_mp_usr_fmt (ptr + 1);
  468.       break;
  469.       /* JF extension: read uset-settable options */
  470.     case 'O':
  471.       a0 = next_a0;
  472.       read_mp_options (ptr + 2);
  473.       next_a0 = a0;
  474.       a0 = sylk_a0;
  475.       break;
  476.     default:
  477.     bad_field:
  478.       a0 = old_a0;
  479.       if (!ismerge)
  480.         clear_spreadsheet ();
  481.       io_recenter_all_win ();
  482.       io_error_msg ("Line %d: Unknown SYLK line \"%s\"", lineno, cbuf);
  483.       return;
  484.     }
  485.     }
  486.   a0 = next_a0;
  487.   io_recenter_all_win ();
  488. }
  489.  
  490.  
  491.  
  492. static char *
  493. sylk_fmt_to_str (f1)
  494.      int f1;
  495. {
  496.   static char p_buf[40];
  497.   int p1;
  498.  
  499.   p_buf[1] = '\0';
  500.   switch (f1)
  501.     {
  502.     case FMT_DEF:
  503.       p_buf[0] = 'D';
  504.       break;
  505.     case FMT_HID:
  506.       p_buf[0] = 'H';
  507.       break;
  508.     case FMT_GPH:
  509.       p_buf[0] = '*';
  510.       break;
  511.     default:
  512.       p1 = GET_PRC (f1);
  513.       if (p1 == PRC_FLT)
  514.     {
  515.       p_buf[1] = 'F';
  516.       p_buf[2] = '\0';
  517.     }
  518.       else
  519.     sprintf (&p_buf[1], "%d", p1);
  520.       switch (f1 | PRC_FLT)
  521.     {
  522.     case FMT_USR:
  523.       p_buf[0] = 'U';
  524.       break;
  525.     case FMT_GEN:
  526.       p_buf[0] = 'G';
  527.       break;
  528.     case FMT_DOL:
  529.       p_buf[0] = '$';
  530.       break;
  531.     case FMT_PCT:
  532.       p_buf[0] = '%';
  533.       break;
  534.     case FMT_FXT:
  535.       p_buf[0] = 'F';
  536.       break;
  537.     case FMT_CMA:
  538.       p_buf[0] = ',';
  539.       break;
  540.     case FMT_EXP:
  541.       p_buf[0] = 'E';
  542.       break;
  543.     default:
  544.       p_buf[0] = '?';
  545.       break;
  546.     }
  547.       break;
  548.     }
  549.   return p_buf;
  550. }
  551.  
  552. static char
  553. jst_to_chr (just)
  554.      int just;
  555. {
  556.   switch (just)
  557.     {
  558.     case JST_DEF:
  559.       return 'D';
  560.     case JST_LFT:
  561.       return 'L';
  562.     case JST_RGT:
  563.       return 'R';
  564.     case JST_CNT:
  565.       return 'C';
  566.     default:
  567.       return '?';
  568.     }
  569. }
  570.  
  571. static FILE *sylk_fp;
  572. static struct rng *sylk_rng;
  573.  
  574. static void
  575. sylk_write_var (name, var)
  576.      char *name;
  577.      struct var *var;
  578. {
  579.   if (var->var_flags == VAR_UNDEF && (!var->var_ref_fm || var->var_ref_fm->refs_used == 0))
  580.     return;
  581.   switch (var->var_flags)
  582.     {
  583.     case VAR_UNDEF:
  584.       break;
  585.     case VAR_CELL:
  586.       if (var->v_rng.lr >= sylk_rng->lr && var->v_rng.lr <= sylk_rng->hr && var->v_rng.lc >= sylk_rng->lc && var->v_rng.lc <= sylk_rng->hc)
  587.     (void) fprintf (sylk_fp, "NN;N%s;E%s\n", var->var_name, cell_name (var->v_rng.lr, var->v_rng.lc));
  588.       break;
  589.     case VAR_RANGE:
  590.       if (var->v_rng.lr < sylk_rng->lr || var->v_rng.hr > sylk_rng->hr || var->v_rng.lc < sylk_rng->lc || var->v_rng.hc > sylk_rng->hc)
  591.     break;
  592.  
  593.       (void) fprintf (sylk_fp, "NN;N%s;E%s\n", var->var_name, range_name (&(var->v_rng)));
  594.       break;
  595. #ifdef TEST
  596.     default:
  597.       panic ("Unknown var type %d", var->var_flags);
  598. #endif
  599.     }
  600. }
  601.  
  602. static void
  603. write_mp_windows (fp)
  604.      FILE *fp;
  605. {
  606.   struct line line;
  607.   line.alloc = 0;
  608.   line.buf = 0;
  609.   io_write_window_config (&line);
  610.   fputs (line.buf, fp);
  611.   free (line.buf);
  612. }
  613.  
  614. void
  615. sylk_write_file (fp, rng)
  616.      FILE *fp;
  617.      struct rng *rng;
  618. {
  619.   CELLREF r, c;
  620.   CELL *cp;
  621.   CELLREF crow = 0, ccol = 0;
  622.   unsigned short w;
  623.  
  624.   /* struct var *var; */
  625.   int old_a0;
  626.  
  627.   (void) fprintf (fp, "ID;POLEO\n");
  628.  
  629.   /* If no range given, write the entire file */
  630.   if (!rng)
  631.     {
  632.       int n;
  633.       int fmts;
  634.       char *data[9];
  635.  
  636.       rng = &all_rng;
  637.  
  638.       (void) fprintf (fp, "F;D%s%c%u\n", sylk_fmt_to_str (default_fmt),
  639.               jst_to_chr (default_jst), default_width); 
  640.  
  641.       fmts = usr_set_fmts ();
  642.       for (n = 0; n < 16; n++)
  643.     {
  644.       if (fmts & (1 << n))
  645.         {
  646.           get_usr_stats (n, data);
  647.           fprintf (fp, "U;N%u;P%s;S%s", n + 1, data[7], data[8]);
  648.           if (data[0][0])
  649.         fprintf (fp, ";HP%s", data[0]);
  650.           if (data[1][0])
  651.         fprintf (fp, ";HN%s", data[1]);
  652.           if (data[2][0])
  653.         fprintf (fp, ";TP%s", data[2]);
  654.           if (data[3][0])
  655.         fprintf (fp, ";TN%s", data[3]);
  656.           if (data[4][0])
  657.         fprintf (fp, ";Z%s", data[4]);
  658.           if (data[5][0])
  659.         fprintf (fp, ";C%s", data[5]);
  660.           if (data[6])
  661.         fprintf (fp, ";D%s", data[6]);
  662.           putc ('\n', fp);
  663.         }
  664.     }
  665.       write_mp_options (fp);
  666.  
  667.       (void) fprintf (fp, "B;Y%u;X%u\n", highest_row (), highest_col ());
  668.  
  669.     }
  670.  
  671.   old_a0 = a0;
  672.   a0 = sylk_a0;
  673.  
  674.   find_widths (rng->lc, rng->hc);
  675.   w = next_width (&c);
  676.   while (w)
  677.     {
  678.       CELLREF cc, ccc;
  679.       unsigned short ww;
  680.       cc = c;
  681.       do
  682.     ww = next_width (&ccc);
  683.       while (ccc == ++cc && ww == w);
  684.       (void) fprintf (fp, "F;W%u %u %u\n", c, cc - 1, w - 1);
  685.       c = ccc;
  686.       w = ww;
  687.     }
  688.  
  689.   find_heights (rng->lr, rng->hr);
  690.   w = next_height (&c);
  691.   while (w)
  692.     {
  693.       CELLREF rr, rrr;
  694.       unsigned short ww;
  695.  
  696.       rr = r;
  697.       do
  698.     ww = next_height (&rrr);
  699.       while (rrr == ++rr && ww == w);
  700.       (void) fprintf (fp, "F;H%u %u %u\n", r, rr - 1, w - 1);
  701.       r = rrr;
  702.       w = ww;
  703.     }
  704.  
  705.   sylk_fp = fp;
  706.   sylk_rng = rng;
  707.   for_all_vars (sylk_write_var);
  708.   find_cells_in_range (rng);
  709.   while (cp = next_row_col_in_range (&r, &c))
  710.     {
  711.       char *ptr;
  712.       int f1, j1;
  713.       char p_buf[40];
  714.  
  715.       f1 = GET_FMT (cp);
  716.       j1 = GET_JST (cp);
  717.       if (f1 != FMT_DEF || j1 != JST_DEF)
  718.     {
  719.       (void) fprintf (fp, "F;");
  720.       if (c != ccol)
  721.         {
  722.           (void) fprintf (fp, "X%u;", c);
  723.           ccol = c;
  724.         }
  725.       if (r != crow)
  726.         {
  727.           (void) fprintf (fp, "Y%u;", r);
  728.           crow = r;
  729.         }
  730.       (void) fprintf (fp, "F%s%c\n", sylk_fmt_to_str (f1), jst_to_chr (j1));
  731.     }
  732.  
  733.       if (!GET_TYP (cp) && !cp->cell_formula)
  734.     continue;
  735.  
  736.       (void) fprintf (fp, "C;");
  737.       if (c != ccol)
  738.     {
  739.       (void) fprintf (fp, "X%u;", c);
  740.       ccol = c;
  741.     }
  742.       if (r != crow)
  743.     {
  744.       (void) fprintf (fp, "Y%u;", r);
  745.       crow = r;
  746.     }
  747.  
  748.       if (cp->cell_formula)
  749.     {
  750.       (void) fprintf (fp, "E%s", decomp (r, c, cp));
  751.       decomp_free ();
  752.     }
  753.  
  754.       switch (GET_TYP (cp))
  755.     {
  756.     case 0:
  757.       ptr = 0;
  758.       break;
  759.     case TYP_STR:
  760.       ptr = 0;
  761.       if (cp->cell_formula)
  762.         putc (';', fp);
  763.       (void) fprintf (fp, "K\"%s\"", cp->cell_str);
  764.       break;
  765.     case TYP_FLT:
  766.       ptr = flt_to_str (cp->cell_flt);
  767.       break;
  768.     case TYP_INT:
  769.       sprintf (p_buf, "%ld", cp->cell_int);
  770.       ptr = p_buf;
  771.       break;
  772.     case TYP_BOL:
  773.       ptr = bname[cp->cell_bol];
  774.       break;
  775.     case TYP_ERR:
  776.       ptr = ename[cp->cell_err];
  777.       break;
  778.     default:
  779.       ptr = 0;
  780. #ifdef TEST
  781.       panic ("What cell type %d", GET_TYP (cp));
  782. #endif
  783.     }
  784.  
  785.       if (ptr)
  786.     {
  787.       if (cp->cell_formula)
  788.         putc (';', fp);
  789.       (void) fprintf (fp, "K%s", ptr);
  790.     }
  791.       if (GET_LCK (cp) == LCK_LCK)
  792.     (void) fprintf (fp, ";P");
  793.  
  794.       putc ('\n', fp);
  795.     }
  796.  
  797.   if (rng == &all_rng)
  798.     write_mp_windows (fp);
  799.  
  800.   (void) fprintf (fp, "E\n");
  801.   a0 = old_a0;
  802. }
  803.  
  804. int
  805. sylk_set_options (set_opt, option)
  806.      int set_opt;
  807.      char *option;
  808. {
  809.   return -1;
  810. }
  811.  
  812. void
  813. sylk_show_options ()
  814. {
  815.   io_text_line ("File format: sylk  (Microsoft Multiplan interchange format)");
  816. }
  817.